import { truthy } from '@gnlab/utils'
import { App, Button } from 'antd'
import config from '@/config'
import { Video } from '@/desktop/components'
import formatAssetUrl from '@/desktop/logics/format-asset-url'
import { getVideoInfo } from '@/lib/utils'
import { commonS } from './common-styles'
import { type BaseProps, type CommonProps, propsWithDefaults, useUpload } from './logics'

type VideoProps = BaseProps<string | null> & Pick<CommonProps, 'rectLimit' | 'duration'>

export function UploadVideo(props: VideoProps) {
  const { message } = App.useApp()
  const {
    cdn,
    tips,
    sizeLimit,
    rectLimit,
    duration,
    value = null,
    onChange,
  } = propsWithDefaults(props)
  const usedSizeLimit = sizeLimit || config.MAX_FILESIZE
  const [uploading, upload] = useUpload(cdn)
  const inputRef = useRef<HTMLInputElement>(null)

  const inputOnChange = useCallback(
    async (e: React.ChangeEvent<HTMLInputElement>) => {
      const file = e.target.files?.[0] ?? null
      e.target.value = ''

      if (file) {
        const size = file.size
        if (size > 1024 * 1024 * usedSizeLimit) {
          void message.warning(`视频文件不能大于${usedSizeLimit}M`)
          return
        }

        if (!!rectLimit || duration) {
          const { width, height, duration: videoDuration } = await getVideoInfo(file)
          if (rectLimit && (width > rectLimit.width || height > rectLimit.height)) {
            void message.warning(`视频尺寸不能大于${rectLimit.width} * ${rectLimit.height}像素`)
            return
          }
          if (duration && videoDuration > duration) {
            void message.warning(`视频长度不能超过${duration}s`)
            return
          }
        }

        const uploaded = await upload(file)
        if (uploaded) onChange(uploaded.url)
      }
    },
    [usedSizeLimit, rectLimit, duration, upload, onChange, message],
  )

  return <div css={commonS.upload}>
    {truthy(value) ? <Video css={s.video} key={value} src={formatAssetUrl(value)} /> : null}

    <div css={s.actions}>
      <Button loading={uploading} onClick={() => inputRef.current?.click()}>
        {truthy(value) ? '重新上传' : '上传视频'}
      </Button>
      {truthy(value) ? (
        <Button loading={uploading} danger onClick={() => onChange(null)}>
          删除
        </Button>
      ) : null}
    </div>

    <div css={commonS.uploadTips}>{truthy(tips) ? tips : `视频文件不得超过${usedSizeLimit}M`}</div>
    <input type="file" accept="video/*" ref={inputRef} onChange={inputOnChange} />
  </div>
}

const s = {
  video: css`
    margin-bottom: 12px;
    video {
      max-width: 300px;
      max-height: 300px;
    }
  `,
  actions: css`
    button:not(:last-child) {
      margin-right: 1.5em;
    }
  `,
}
